package com.itxiuyixiu.volunteer.service;

import com.itxiuyixiu.entity.enums.AuthorityType;
import com.itxiuyixiu.entity.mapper.StudentReaderMapper;
import com.itxiuyixiu.entity.mapper.UserReadMapper;
import com.itxiuyixiu.entity.mapper.UserWriterMapper;
import com.itxiuyixiu.entity.model.Student;
import com.itxiuyixiu.entity.model.User;
import com.itxiuyixiu.tools.security.user.GetUser;
import com.itxiuyixiu.volunteer.common.errors.ServiceException;
import com.itxiuyixiu.volunteer.dto.UserForgetPasswordParam;
import com.itxiuyixiu.volunteer.dto.UserModifyMessageParam;
import com.itxiuyixiu.volunteer.dto.UserRegisterParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Optional;

//import sun.security.jgss.GSSToken;


/**
 * @author 黄磊
 * @date 2020/5/2
 */
@Slf4j
@Service
public class UserCommonService {
    @Resource
    private UserWriterMapper userWriterMapper;
    @Resource
    private UserReadMapper userReadMapper;
    @Resource
    private StudentReaderMapper studentReaderMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private VerificationService verificationService;

    /**
     * 用户注册
     *
     * @param dto 注册信息
     * @return 用户id
     */
    public Integer saveUser(UserRegisterParam dto) {
        if (isEmailUsed(dto.getUsername())) {
            throw new ServiceException("邮箱已被他人使用，请换一个邮箱");
        }
        if (!verificationService.checkVerification(dto.getUsername(), dto.getVerification())) {
            throw new ServiceException("邮箱验证码错误");
        }
        Optional<User> userOptional = userReadMapper.findUserByUsername(dto.getUsername());
        if (userOptional.isPresent()) {
            throw new ServiceException("用户已经被注册");
        }
        User user = new User();
        user.setUsername(dto.getUsername());
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        user.setAuthorities(AuthorityType.ROLE_USER);
        user.setUserEmail(dto.getUsername());
        user.setNickName(dto.getUsername());
        userWriterMapper.saveUser(user);
        log.debug("成功创建用户：" + user.getUsername());
        return user.getUserId();
    }

    /**
     * 获取当前用户信息
     *
     * @return 当前用户信息
     */
    public User findUserMessage() {
        Optional<User> userOptional = userReadMapper.findUserByUsername(GetUser.getUserName());
        if (!userOptional.isPresent()) {
            throw new ServiceException("用户信息不存在");
        }
        User user = userOptional.get();
        Optional<Student> studentOptional = studentReaderMapper.findStudentByUserId(user.getUserId());
        if (!studentOptional.isPresent()) {
            user.setIsStudent(false);
            return user;
        } else {
            user.setIsStudent(true);
            user.setStudent(studentOptional.get());
        }
        return user;
    }

    /**
     * 修改用户信息
     *
     * @param userDto 用户信息
     */
    public void modifyUser(UserModifyMessageParam userDto) {
        User user = findUser();
        user.setNickName(userDto.getNickName());
        user.setUserEmail(userDto.getUserEmail());
        user.setHeadImage(userDto.getHeadImage());
        userWriterMapper.modifyUserById(user);
        log.info("用户" + user.getUsername() + "成功修改自己个人信息");
    }

    /**
     * 修改密码
     *
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     */
    public void modifyPassword(String oldPassword, String newPassword) {
        User user = findUser();
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new ServiceException("旧密码错误");
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        userWriterMapper.modifyUserById(user);
        log.info("用户" + user.getUsername() + "成功修改自己密码");
    }

    /**
     * 用户的忘记密码
     *
     * @param dto 信息
     */
    public void forgetPassword(UserForgetPasswordParam dto) {
        if (!verificationService.checkVerification(dto.getUserEmail(), dto.getVerification())) {
            throw new ServiceException("验证码不正确");
        }
        Optional<User> userOptional = userReadMapper.findUserByUsername(dto.getUsername());
        if (!userOptional.isPresent()) {
            throw new ServiceException("账号不存在");
        }
        User user = userOptional.get();
        if (!user.getUserEmail().equals(dto.getUserEmail())) {
            throw new ServiceException("邮箱与账户邮箱不符");
        }
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        userWriterMapper.modifyUserById(user);
        log.info("用户" + user.getUsername() + "成功重置自己密码");
    }

    /**
     * 查看邮箱是否被使用
     *
     * @param email 邮箱
     * @return true—邮箱已被使用，false—邮箱未被使用
     */
    public boolean isEmailUsed(String email) {
        return userReadMapper.isEmailUsed(email);
    }

    private User findUser() {
        return userReadMapper.findUserByUsername(GetUser.getUserName()).orElseThrow(() -> new ServiceException("用户信息不存在"));
    }
}
